package com.yeziji.config.rabbitMq;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * Rabbit MQ 配置
 *
 * @author hwy
 * @since 2024/10/25 15:02
 **/
@Slf4j
@Configuration
public class RabbitMqConfig {
    @Resource
    private ConnectionFactory connectionFactory;

    @Bean
    public RabbitTemplate getRabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        // 发送消息时设置强制标志，仅当提供了returnCallback时才适用
        rabbitTemplate.setMandatory(true);
        // 确保消息是否发送到交换机，成功与失败都会触发
        rabbitTemplate.setConfirmCallback(this.getRabbitMqConfirmCallback());
        // 确保消息是否发送到队列，成功发送不触发，失败触发
        rabbitTemplate.setReturnsCallback(this.getRabbitMqReturnCallback());
        // 消息序列化
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
        // 反序列化
        return new Jackson2JsonMessageConverter(objectMapper);
    }

    @Bean
    public RabbitMqConfirmCallback getRabbitMqConfirmCallback() {
        return new RabbitMqConfirmCallback();
    }

    @Bean
    public RabbitMqReturnCallback getRabbitMqReturnCallback() {
        return new RabbitMqReturnCallback();
    }

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory);
        // 监听器是否暴露出 channel
        simpleMessageListenerContainer.setExposeListenerChannel(true);
        // 设置每个消费者获取的最大的消息数量
        simpleMessageListenerContainer.setPrefetchCount(10);
        // 设置确认模式为手工确认
        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        // 监听处理类
        simpleMessageListenerContainer.setMessageListener(new RabbitMqListener());
        return simpleMessageListenerContainer;
    }
}